/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <pthread.h>
#include <cutils/memory.h>

#include <utils/Log.h>

//#include <system/window.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>

#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>

#define CHECK_RET() do{ if(ret) \
 printf("error:\t\tline:%d ret:%d\n", __LINE__, ret); \
 else \
    printf("OK:\t\tline:%d ret:%d\n", __LINE__, ret); \
} while(0)

using namespace android;

static sp<SurfaceComposerClient> client;
static sp<SurfaceControl> surfaceControl;
static int slot,width=1920,height=1080;
static sp<GraphicBuffer> buf;
static sp<ISurfaceTexture> mIST;
static sp<Fence> fence;
static void* img = NULL;

void* app_fix_buff_lock(){
    int ret = 0;
    ret = mIST->dequeueBuffer(&slot, fence, width, height, PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_WRITE_OFTEN);
    printf("dequeueBuffer:%d slot:%d\n", ret, slot);

    ret = mIST->requestBuffer(slot, &buf);
    CHECK_RET();
    ret = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    CHECK_RET();
    printf("buffer address:%d\n", img);
}

void app_fix_buff_unlock_and_post(){
    buf->unlock();
    int64_t timestamp;
    timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
    Rect crop(width, height);
    ISurfaceTexture::QueueBufferOutput output;
    ISurfaceTexture::QueueBufferInput input(timestamp, crop, NATIVE_WINDOW_SCALING_MODE_FREEZE,
            0, fence);
    int ret = mIST->queueBuffer(slot, input, &output);
    CHECK_RET();
}


void sys_app_updateFrame(){
    app_fix_buff_lock();
    app_fix_buff_unlock_and_post();
}

static void start_test(void* buf);
int main(int argc, char** argv)
{
    printf("entry main\n");

    sp<SurfaceComposerClient> client = new SurfaceComposerClient();

    sp<SurfaceControl> surfaceControl = client->createSurface(
            String8("surface"), width, height, PIXEL_FORMAT_RGBA_8888, 0);
    SurfaceComposerClient::openGlobalTransaction();
    surfaceControl->setLayer(100000);
    SurfaceComposerClient::closeGlobalTransaction();
    mIST =  surfaceControl->getSurface()->getSurfaceTexture();

    app_fix_buff_lock();
    memset(img, 128, width*height*4);
    app_fix_buff_unlock_and_post();

    start_test(img);

    printf("test complete. CTRL+C to finish.\n");

   // while(1){
   //  sys_app_updateFrame();
   // }

    sleep(50);

    return 0;
}

static void* pixels;
static int size;

static pthread_t thread_test;
static void *test_fun(void* arg){
    fprintf(stdout, "Test thread run\n");
    fflush(stdout);

    int value=128;

    for(int i=0;i <128; i++){
        app_fix_buff_lock();
        memset(pixels, value>>i, size);
        app_fix_buff_unlock_and_post();
        sleep(1);
    }

    fprintf(stdout, "Test thread end.\n");
}

static void start_test(void* buf){
    fprintf(stdout, "Start Test thread, bufffer:%p\n", buf);
    pixels = buf;
    pthread_create(&thread_test, NULL, &test_fun, NULL);
}